<template>
  <div class="material">
    <div class="material__left">
      <div class="flex-1 min-h-0">
        <el-scrollbar>
          <div class="pt-4 material-left__content p-b-4">
            <el-tree
                ref="treeRef"
                node-key="id"
                :data="cateLists"
                empty-text="''"
                :highlight-current="true"
                :expand-on-click-node="false"
                :current-node-key="cateId"
                @node-click="handleCatSelect"
            >
              <template v-slot="{ data }">
                <div class="flex flex-1 items-center pr-4 min-w-0">
                  <img class="w-[20px] h-[16px] mr-3" src="/@/assets/icon_folder.png"/>
                  <span class="flex-1 mr-2 truncate">
										{{ data.name }}
									</span>
                  <el-dropdown v-if="data.id > 0" :hide-on-click="false">
                    <span class="muted m-r-10">···</span>
                    <template #dropdown>
                      <el-dropdown-menu>
                        <popover-input
                            @confirm="handleEditCate($event, data.id)"
                            size="default"
                            :value="data.name"
                            width="400px"
                            :limit="20"
                            show-limit
                            teleported
                        >
                          <div>
                            <el-dropdown-item> {{ $t('material.editGroup') }}</el-dropdown-item>
                          </div>
                        </popover-input>
                        <div @click="handleDeleteCate(data.id)">
                          <el-dropdown-item>{{ $t('material.delGroup') }}</el-dropdown-item>
                        </div>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </div>
              </template>
            </el-tree>
          </div>
        </el-scrollbar>
      </div>

      <div class="flex justify-center p-2 border-t border-br">
        <popover-input @confirm="handleAddCate" size="default" width="400px" :limit="20" show-limit teleported>
          <el-button> {{ $t('material.addGroup') }}</el-button>
        </popover-input>
      </div>
    </div>
    <div class="flex flex-col material__center">
      <div class="flex operate-btn">
        <div class="flex flex-1">
          <el-button icon="folder-add" type="primary" class="ml10" v-auth="'sys_file_del'" @click="visibleUpload = true"
          >{{ $t('material.uploadFileTip') }}
          </el-button>

          <el-button v-if="mode == 'page'" :disabled="!select.length" @click.stop="batchFileDelete()">
            {{ $t('common.delBtn') }}
          </el-button>

          <popup v-if="mode == 'page'" class="ml-3" @confirm="batchFileMove" :disabled="!select.length"
                 :title="$t('material.moveBtn')">
            <template #trigger>
              <el-button :disabled="!select.length">{{ $t('material.moveBtn') }}</el-button>
            </template>

            <div>
              <span class="mr-5">移动文件至</span>
              <el-select v-model="moveId" placeholder="请选择">
                <template v-for="item in cateLists" :key="item.id">
                  <el-option v-if="item.id !== ''" :label="item.name" :value="item.id"></el-option>
                </template>
              </el-select>
            </div>
          </popup>
        </div>
        <el-input class="mr-16 ml-80" :placeholder="$t('file.inputfileNameTip')" v-model="fileParams.original"
                  @keyup.enter="refresh">
          <template #append>
            <el-button @click="refresh">
              <template #icon>
                <el-icon>
                  <Search/>
                </el-icon>
              </template>
            </el-button>
          </template>
        </el-input>
        <div class="flex gap-2 items-center">
          <el-tooltip :content="$t('material.list')" placement="top">
            <div
                class="flex justify-center items-center w-8 h-8 list-icon"
                :class="{
                  'bg-primary-light-8 text-primary': listShowType === 'table'
                }"
                @click="listShowType = 'table'"
            >
              <el-icon>
                <Expand/>
              </el-icon>
            </div>
          </el-tooltip>
          <el-tooltip :content="$t('material.grid')" placement="top">
            <div
                class="flex justify-center items-center w-8 h-8 list-icon"
                :class="{
                  'bg-primary-light-8 text-primary': listShowType === 'normal'
                }"
                @click="listShowType = 'normal'"
            >
              <el-icon>
                <Menu/>
              </el-icon>
            </div>
          </el-tooltip>
        </div>
      </div>
      <div class="mt-3" v-if="mode == 'page'">
        <el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
                     :indeterminate="isIndeterminate">
          {{ $t('material.allCheck') }}
        </el-checkbox>
      </div>
      <div class="flex flex-col flex-1 mb-1 min-h-0 material-center__content">
        <el-scrollbar v-if="pager.lists.length" v-show="listShowType == 'normal'">
          <ul class="flex flex-wrap mt-4 file-list">
            <li class="file-item-wrap" v-for="item in pager.lists" :key="item.id" :style="{ width: fileSize }">
              <del-wrap @close="batchFileDelete([item.id])">
                <file-item :uri="getFileUri(item)" :file-size="fileSize" :type="type" @click="selectFile(item)">
                  <div class="item-selected" v-if="isSelect(item.id)">
                    <el-icon class="el-input__icon">
                      <Check/>
                    </el-icon>
                  </div>
                </file-item>
              </del-wrap>
              <div class="flex justify-center items-center mt-2">
                {{ item.original }}
              </div>
              <div class="flex justify-center items-center operation-btns">
                <popover-input
                    @confirm="handleFileRename($event, item.id)"
                    size="default"
                    :value="item.name"
                    width="400px"
                    :limit="50"
                    show-limit
                    teleported
                >
                  <el-button type="primary" link> {{ $t('material.rename') }}</el-button>
                </popover-input>
                <el-button type="primary" link @click="handleDownFile(item)"> {{ $t('material.download') }}</el-button>
                <el-button type="primary" link @click="handlePreview(item)"> {{ $t('material.view') }}</el-button>
              </div>
            </li>
          </ul>
        </el-scrollbar>

        <el-table
            ref="tableRef"
            class="mt-4"
            v-show="listShowType == 'table'"
            :data="pager.lists"
            width="100%"
            height="100%"
            size="large"
            @row-click="selectFile"
        >
          <el-table-column width="55">
            <template #default="{ row }">
              <el-checkbox :modelValue="isSelect(row.id)" @change="selectFile(row)"/>
            </template>
          </el-table-column>
          <el-table-column label="图片" width="100">
            <template #default="{ row }">
              <file-item :uri="getFileUri(row)" file-size="50px" :type="type"></file-item>
            </template>
          </el-table-column>
          <el-table-column label="名称" min-width="100" show-overflow-tooltip>
            <template #default="{ row }">
              <el-link @click.stop="handlePreview(getFileUri(row))" :underline="false">
                {{ row.original }}
              </el-link>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="上传时间" min-width="100"/>
          <el-table-column label="操作" width="150" fixed="right">
            <template #default="{ row }">
              <div class="inline-block">
                <popover-input
                    @confirm="handleFileRename($event, row.id)"
                    size="default"
                    :value="row.name"
                    width="400px"
                    :limit="50"
                    show-limit
                    teleported
                >
                  <el-button type="primary" link> 重命名</el-button>
                </popover-input>
              </div>
              <div class="inline-block">
                <el-button type="primary" link @click.stop="handlePreview(getFileUri(row))"> 查看</el-button>
              </div>
              <div class="inline-block">
                <el-button type="primary" link @click.stop="batchFileDelete([row.id])"> 删除</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>

        <div class="flex flex-1 justify-center items-center" v-if="!pager.lists.length">{{
            $t('el.transfer.noData')
          }}~
        </div>
      </div>
      <div>
        <pagination v-bind="pager" @current-change="currentChangeHandle" layout="total, prev, pager, next, jumper"/>
      </div>
    </div>
    <div class="material__right" v-if="mode == 'picker'">
      <div class="flex flex-wrap justify-between p-2">
        <div class="flex items-center sm">
          已选择 {{ select.length }}
          <span v-if="limit">/{{ limit }}</span>
        </div>
        <el-button type="primary" link @click="clearSelect">清空</el-button>
      </div>
      <div class="flex-1 min-h-0">
        <el-scrollbar class="ls-scrollbar">
          <ul class="flex flex-col select-lists p-t-3">
            <li class="mb-4" v-for="item in select" :key="item.id">
              <div class="select-item">
                <del-wrap @close="cancelSelete(item.id)">
                  <file-item :uri="item.uri" file-size="100px" :type="type"></file-item>
                </del-wrap>
              </div>
            </li>
          </ul>
        </el-scrollbar>
      </div>
    </div>
    <preview v-model="showPreview" :url="previewUrl" :type="type" :fileName="fileName"/>
  </div>

  <el-dialog :title="$t('material.uploadFileTip')" v-model="visibleUpload" :destroy-on-close="true" draggable>
    <upload-file @change="refresh" v-if="props.type === 'image'" :data="{ groupId: cateId, type: typeValue }"
                 :fileType="['png', 'jpg', 'jpeg']"/>

    <upload-file @change="refresh" v-if="props.type === 'video'" :data="{ groupId: cateId, type: typeValue }"
                 :fileType="['mp4']"/>

    <upload-file
        @change="refresh"
        v-if="props.type === 'file'"
        :data="{ cid: cateId, type: typeValue }"
        :fileType="['doc', 'xls', 'ppt', 'txt', 'pdf', 'docx', 'xlsx', 'pptx']"
    />
  </el-dialog>
</template>

<script lang="ts" setup>
const Popup = defineAsyncComponent(() => import('/@/components/Popup/index.vue'));
const PopoverInput = defineAsyncComponent(() => import('/@/components/PopoverInput/index.vue'));
import {useCate, useFile} from './hook';
import FileItem from './file.vue';
import Preview from './preview.vue';
import type {Ref} from 'vue';
import other from '/@/utils/other';

const {proxy} = getCurrentInstance();
const kkServerURL = import.meta.env.VITE_KK_SERVER_URL
const props = defineProps({
  fileSize: {
    type: String,
    default: '100px',
  },
  limit: {
    type: Number,
    default: 1,
  },
  type: {
    type: String,
    default: 'image',
  },
  mode: {
    type: String,
    default: 'picker',
  },
  pageSize: {
    type: Number,
    default: 15,
  },
});
const emit = defineEmits(['change']);
const {limit} = toRefs(props);
const typeValue = computed<number>(() => {
  switch (props.type) {
    case 'image':
      return 10;
    case 'video':
      return 20;
    case 'file':
      return 30;
    default:
      return 0;
  }
});
const visible: Ref<boolean> = ref(false);
const visibleUpload: Ref<boolean> = ref(false);
const previewUrl = ref('');
const fileName = ref('');
const showPreview = ref(false);
const {
  treeRef,
  cateId,
  cateLists,
  handleAddCate,
  handleEditCate,
  handleDeleteCate,
  getCateLists,
  handleCatSelect
} = useCate(typeValue.value);

const {
  tableRef,
  listShowType,
  moveId,
  pager,
  fileParams,
  select,
  isCheckAll,
  isIndeterminate,
  getFileList,
  refresh,
  batchFileDelete,
  batchFileMove,
  selectFile,
  isSelect,
  clearSelect,
  cancelSelete,
  selectAll,
  handleFileRename,
} = useFile(cateId, typeValue, limit, props.pageSize);

/**
 * 获取数据
 */
const getData = async () => {
  await getCateLists();
  treeRef.value?.setCurrentKey(cateId.value);
  getFileList();
};

/**
 * 当前页码改变事件处理函数
 * @param val 新的页码
 */
const currentChangeHandle = (val: number) => {
  // 修改state.pagination中的current属性
  pager.current = val;
  // 再次发起查询操作
  getFileList();
};

/**
 * 处理预览
 *
 * @param {string} item - 资源
 */
const handlePreview = (item: { fileName: string }) => {
  previewUrl.value = getFileUri(item);
  showPreview.value = true;
  fileName.value = item.fileName;
};

/**
 * 处理下载文件
 *
 * @param {any} item - 文件项对象
 */
const handleDownFile = (item: any) => {
  other.downBlobFile(`/admin/sys-file/oss/file?fileName=${item.fileName}`, {}, item.original);
};

watch(
    visible,
    async (val: boolean) => {
      if (val) {
        getData();
      }
    },
    {
      immediate: true,
    }
);
watch(cateId, () => {
  fileParams.name = '';
  refresh();
});

watch(
    select,
    (val: any[]) => {
      emit('change', val);
      if (val.length == pager.lists.length && val.length !== 0) {
        isIndeterminate.value = false;
        isCheckAll.value = true;
        return;
      }
      if (val.length > 0) {
        isIndeterminate.value = true;
      } else {
        isCheckAll.value = false;
        isIndeterminate.value = false;
      }
    },
    {
      deep: true,
    }
);

const getFileUri = (item: any) => {
  return `${proxy.baseURL}/admin/sys-file/oss/file?fileName=${item.fileName}`;
};

onMounted(() => {
  props.mode == 'page' && getData();
});

defineExpose({
  clearSelect,
});
</script>

<style scoped lang="scss">
.material {
  @apply h-full min-h-0 flex flex-1;
  &__left {
    @apply border-r border-br flex flex-col w-[200px];
    :deep(.el-tree-node__content) {
      height: 36px;
    }
  }

  &__center {
    flex: 1;
    min-width: 0;
    min-height: 0;
    padding: 16px 16px 0;

    .list-icon {
      @apply rounded transition-colors duration-200 cursor-pointer hover:bg-gray-100;
    }

    .file-list {
      .file-item-wrap {
        margin-right: 16px;
        line-height: 1.3;
        cursor: pointer;

        .item-selected {
          display: flex;
          align-items: center;
          justify-content: center;
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          border-radius: 4px;
          background-color: rgba(0, 0, 0, 0.5);
          box-sizing: border-box;
        }

        .operation-btns {
          height: 28px;
          visibility: hidden;
        }

        &:hover .operation-btns {
          visibility: visible;
        }
      }
    }
  }

  &__right {
    @apply border-l border-br flex flex-col;
    width: 130px;

    .select-lists {
      padding: 10px;

      .select-item {
        width: 100px;
        height: 100px;
      }
    }
  }
}
</style>
